﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Quexcel.OpenXML.Interfaces;
using System.Xml;
using System.IO.Packaging;
using System.Text.RegularExpressions;

namespace Quexcel.OpenXML.Excel.Workbook.IO
{
    internal class WorkbookReader : IWorkbookReader
    {
        protected XmlDocument workbookDoc;
        protected PackagePart documentPart;
        protected Package xlPackage;

        internal WorkbookReader(PackagePart documentPart, Package xlPackage)
        {
            workbookDoc = new XmlDocument();
            workbookDoc.Load(documentPart.GetStream());
            this.documentPart = documentPart;
            this.xlPackage = xlPackage;
        }

        #region IReader Members
        public string Read(string addressName)
        {
            throw new NotImplementedException();
        }
        public void Close()
        {
            
        }
        #endregion

        #region IWorkbookReader Members
        public XmlNamespaceManager NameSpaceManager
        {
            get
            {
                XmlNamespaceManager nsManager = new XmlNamespaceManager(workbookDoc.NameTable);
                nsManager.AddNamespace("d", workbookDoc.DocumentElement.NamespaceURI);
                return nsManager;
            }
        }
        public PackagePart GetSheetPart(string sheetName)
        {
            string searchString = string.Format("//d:sheet[@name='{0}']", sheetName);
            XmlNode sheetNode = workbookDoc.SelectSingleNode(searchString, NameSpaceManager);

            if (sheetNode != null)
            {
                XmlAttribute relationAttribute = sheetNode.Attributes["r:id"];
                if (relationAttribute != null)
                {
                    string relId = relationAttribute.Value;
                    PackageRelationship sheetRelation = documentPart.GetRelationship(relId);
                    Uri sheetUri = PackUriHelper.ResolvePartUri(documentPart.Uri, sheetRelation.TargetUri);
                    return xlPackage.GetPart(sheetUri);
                }
            }

            return null;
        }
        public PackagePart GetRangePart(string rangeName, out string sheet, out string range)
        {
            sheet = null;
            range = null;
            string searchString = string.Format("//d:definedName[@name='{0}']", rangeName);
            XmlNode rangeNode = workbookDoc.SelectSingleNode(searchString, NameSpaceManager);

            if (rangeNode != null)
            {
                string[] output = Utils.Util.RangeAddressPattern.Match(rangeNode.InnerText).Result("${sheet}!${startCell}${startRow}:${endCell}${endRow}").Split('!');
                PackagePart rangePart = GetSheetPart(output[0]);
                sheet = output[0];
                range = output[1];

                return rangePart;
            }

            return null;
        }
        public PackagePart GetSharedStringPart()
        {
            foreach (System.IO.Packaging.PackageRelationship relationship
                            in documentPart.GetRelationshipsByType("http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"))
            {
                Uri sharedStringUri = PackUriHelper.
                          ResolvePartUri(documentPart.Uri, relationship.TargetUri);
                return xlPackage.GetPart(sharedStringUri);
            }

            return null;
        }
        #endregion
    }
}
